#include <iostream>

#include "defs.h"
#include "memPage_t.h"

memPage_t::memPage_t(size_t s)
	: pageSize(s)
	, actualSize(0)
	, position(0)
	, next(NULL)
	, prev(NULL)
{
	if(s == 0)
		pageSize = MAXSIZE; // Page size must be positive

	pageData = new char[pageSize];
}

memPage_t::~memPage_t()
{
	delete[] pageData;
}
	
size_t memPage_t::getPosition() const
{
	return position;
}
	
bool memPage_t::setPosition(size_t pos)
{
	if(pos>=pageSize)
		return false;
	
	position = pos;
	return true;
}

size_t memPage_t::getPageSize() const
{
	return pageSize;
}

size_t memPage_t::getActualSize() const
{
	return actualSize;
}

size_t memPage_t::getFreeSize() const
{
	return pageSize - actualSize;
}

bool memPage_t::isPageEmpty() const
{
	return actualSize==0;
}

bool memPage_t::isPageFull() const
{
	return actualSize==pageSize;
}

void memPage_t::read(void* const data, size_t size)
{
	read(data,size,position);
}

void memPage_t::read(void* const data, size_t size, size_t offset)
{
	memcpy((char*)data+offset,pageData+position,size);

	if(position + size == pageSize)
		setPosition(pageSize - 1);
	else
		setPosition(position + size);
}

void memPage_t::write(const void* const data, size_t size, size_t offset)
{
	char* dst = pageData+position;
	memcpy(dst,(char*)data+offset,size);

	// page position will point to next avaliable cell (or last cell if next cell # == pageSize)
	size_t newPos = position+size;
	if(newPos == pageSize)
	{
		setPosition(pageSize - 1);
		actualSize = pageSize;
	}
	else
	{
		setPosition(newPos);
		actualSize = newPos;
	}
}

void memPage_t::setNext(memPage_t* const page)
{
	next = page;
}

void memPage_t::setPrev(memPage_t* const page)
{
	prev = page;
}

memPage_t* memPage_t::getNext() const
{
	return next;
}

memPage_t::memPage_t(const memPage_t& mp)
	: pageSize(mp.pageSize)
	, actualSize(mp.actualSize)
	, position(mp.position)
	, next(mp.next)
	, prev(mp.prev)
{
	pageData = new char[pageSize];
	memcpy(pageData,mp.pageData,pageSize);
}

memPage_t& memPage_t::operator=(const memPage_t& mp)
{
	if(this!=&mp)
	{
		delete[] pageData;

		pageSize=mp.pageSize;
		actualSize=mp.actualSize;
		position=mp.position;
		next=mp.next;
		prev=mp.prev;

		pageData = new char[pageSize];
		memcpy(pageData,mp.pageData,pageSize);
	}
	return *this;
}